# 导入pymysql用于MySQL连接
import pymysql
# 导入连接池模块
from dbutils.pooled_db import PooledDB
# 导入日志记录模块
import logging
# 导入类型注解
from typing import Optional, List, Tuple, Any

# 获取当前模块的logger
logger = logging.getLogger(__name__)
# 设置默认日志级别
logging.basicConfig(level=logging.INFO)


# 定义MySQL客户端类
class MySQLClient:
    """
    MySQL工具类，封装连接池与常用操作
    """

    # 初始化方法，创建连接池
    def __init__(self, host: str, port: int, user: str, password: str, database: str):
        self.pool = PooledDB(
            creator=pymysql,  # 指定数据库驱动
            maxconnections=6,  # 最大连接数
            mincached=2,  # 初始化时最小空闲连接数
            maxcached=5,  # 最大空闲连接数
            maxshared=3,  # 最大共享连接数（对线程不敏感时无实际效果）
            blocking=True,  # 无连接时是否等待
            maxusage=None,  # 单个连接最大复用次数（None表示无限）
            setsession=[],  # 设置会话级别命令
            ping=0,  # 检查连接状态的频率（0表示不检查）
            host=host,  # 数据库地址
            port=port,  # 数据库端口
            user=user,  # 用户名
            password=password,  # 密码
            database=database,  # 数据库名称
            charset='utf8'  # 字符集
        )

    # 获取连接和游标（以字典形式返回结果）
    def _get_conn_cursor(self) -> Tuple[pymysql.connections.Connection, pymysql.cursors.DictCursor]:
        conn = self.pool.connection()  # 从连接池获取连接
        cursor = conn.cursor(pymysql.cursors.DictCursor)  # 获取字典游标
        return conn, cursor

    # 内部统一执行器，封装查询和增删改逻辑
    def _execute(self, sql: str, args: Optional[Tuple] = None, many: bool = False, fetch: bool = False) -> Any:
        conn, cursor = self._get_conn_cursor()  # 获取连接和游标
        try:
            if many:  # 批量操作
                result = cursor.executemany(sql, args)
            else:  # 单条操作
                result = cursor.execute(sql, args)

            if fetch:  # 查询时获取所有结果
                result = cursor.fetchall()

            conn.commit()  # 提交事务
            return result  # 返回结果
        except Exception as e:
            logger.error(f"MySQL执行失败: {e}")  # 打印错误日志
            conn.rollback()  # 回滚事务
        finally:
            cursor.close()  # 关闭游标
            conn.close()  # 关闭连接

    # 查询所有结果
    def fetch_all(self, sql: str, args: Optional[Tuple] = None) -> List[dict]:
        return self._execute(sql, args=args, fetch=True)  # 执行查询并返回字典列表

    # 插入单条记录
    def insert_one(self, sql: str, args: Optional[Tuple] = None) -> int:
        return self._execute(sql, args=args)  # 执行单条插入

    # 批量插入记录
    def insert_batch(self, sql: str, args: List[Tuple]) -> int:
        return self._execute(sql, args=args, many=True)  # 执行批量插入

    # 更新记录
    def update(self, sql: str, args: Optional[Tuple] = None) -> int:
        return self._execute(sql, args=args)  # 执行更新

    # 删除记录
    def delete(self, sql: str, args: Optional[Tuple] = None) -> int:
        return self._execute(sql, args=args)  # 执行删除


# 获取MySQLClient快捷函数（用于创建实例）
def get_mysql_connection(host: str, port: int, user: str, password: str, database: str) -> MySQLClient:
    return MySQLClient(host, port, user, password, database)
